Add Internal v2 API Access Token Generation for Users#3597
Add Internal v2 API Access Token Generation for Users#3597aaronskiba wants to merge 11 commits intoapi_v2_dmponlinefrom
Conversation
Generated by 🚫 Danger |
| authorize current_user, :internal_user_v2_access_token? | ||
| @token = Api::V2::InternalUserAccessTokenService.rotate!(current_user) | ||
| respond_to do |format| | ||
| format.js { render 'users/refresh_token' } |
There was a problem hiding this comment.
Would it be possible for this endpoint to be hit without JS?
There was a problem hiding this comment.
Yes, it's technically possible via a direct POST (but that would fail without proper authentication).
Our UI only initiates this action through JS. This is consistent with the legacy token refresh pattern, where JS rendering is implicit. To reuse refresh_token.js.erb, we need to explicitly add format.js { render 'users/refresh_token' }.
| Doorkeeper::AccessToken.find_by(user_token_filter(user)) | ||
| end | ||
|
|
||
| def rotate!(user) |
There was a problem hiding this comment.
Would it be possible for this to fail in the creation stage? If so, I'm just wondering if we have ample error handling for that scenario.
There was a problem hiding this comment.
I will at least add some handling in case the internal OAuth application is not found.
|
There's two documentation related Rubocop errors
|
a5c24c6 to
23a2230
Compare
- Creates a first-party Doorkeeper client for issuing internal v2 API tokens - Sets redirect_uri to OOB, scopes to 'read', and marks it as confidential - Ensures the internal application exists in all environments before token service is used
ad94297 to
5c24cdf
Compare
This service manages user-scoped v2 API access tokens for internal app users. - Tokens are equivalent to first-party Personal Access Tokens (PATs) and are issued directly to authenticated users, bypassing the full OAuth 2.0 authorization_code flow. - Supports token creation, rotation, and revocation. - Uses Doorkeeper::AccessToken records for consistent scoping, expiry, and revocation handling. - Designed strictly for internal usage; third-party OAuth clients are not supported.
Adds `Api::V2::InternalUserAccessTokensController#create` with Pundit authorization and routing. Also reuses the existing `users/refresh_token.js.erb` response to update the UI via JS. `@success` is read by `app/views/users/refresh_token.js.erb` (similar approach as `UsersController#refresh_token`)
This change updates `app/views/devise/registrations/_api_token.html.erb` to include support for the v2 API access token. Existing v0/v1 token support is retained. - Introduce V2 token lookup via `Api::V2::InternalUserAccessTokenService` - Display a dedicated V2 API access token section with its own regeneration action
This change breaks refactors `_api_token.html.erb` into additional separate partials: 1) app/views/devise/registrations/_legacy_api_token.html.erb 2) app/views/devise/registrations/_v2_api_token.html.erb In addition to the refactor, the following changes have been made: - `<div id="api-token"` has been renamed to `<div id="legacy-api-token"` - A `<div id="api-tokens">` wrapper has been added in app/views/devise/registrations/_api_token.html.erb. - `app/views/users/refresh_token.js.erb` now references the '#api-tokens' wrapper.
The API Access tab is now visible to all users to support the new v2 API token, which is accessible to everyone. The existing v0/v1 legacy token remains restricted and continues to use the previous authorization and rendering logic within the tab.
Styling changes can be viewed at /users/edit#api-details
`InternalUserAccessTokenService`: add `application!` (lookup + raise) and `application_present?` (safe check with logging) `_v2_api_token.html.erb`: gate token UI on `application_present?` and show a warning when missing.
Add request specs for InternalUserAccessTokensController - Include both authenticated & unauthenticated user scenarios - Include both present & absent internal OAuth app scenarios Add service specs for InternalUserAccessTokenService - Test token retrieval, rotation, and OAuth app presence - Verify old token revocation when rotating Add view specs for API token partials - Test legacy partial rendering based on `user.can_use_api?` - Test OAuth application availability scenarios
Add `defaults: { format: :js }` to the internal_user_access_token route, allowing callers to omit the explicit format parameter.
5c24cdf to
6a54ad5
Compare
Changes proposed in this PR:
Summary
This PR introduces support for issuing internal, user-scoped v2 API access tokens, managed entirely within the application (first-party tokens) for internal users.
Key Changes
Create internal Doorkeeper app via rake task
bundle exec rake doorkeeper:ensure_internal_appCreate Api::V2::InternalUserAccessTokenService
Add "POST /api/v2/internal_user_access_token" action & route
Adds
Api::V2::InternalUserAccessTokensController#createwith Pundit authorization and routing. Also reuses the existingusers/refresh_token.js.erbresponse to update the UI via JS.@successis read byapp/views/users/refresh_token.js.erb(similar approach asUsersController#refresh_token)Add API v2 section to /users/edit#api-details
app/views/devise/registrations/_api_token.html.erbto include support for the v2 API access token. Existing v0/v1 token support is retained.Api::V2::InternalUserAccessTokenServiceExpose API Access tab to all users / restrict legacy token rendering
which is accessible to everyone.
Add test coverage for internal v2 token generation
Add request specs for InternalUserAccessTokensController
Add service specs for InternalUserAccessTokenService
Add view specs for API token partials
user.can_use_api?